home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Gfx / Edit / TSMorph / src / RenderSub.c < prev    next >
C/C++ Source or Header  |  1994-10-30  |  25KB  |  972 lines

  1. // TSMorph - Amiga Morphing program
  2. // Copyright (C) © 1993  Topicsave Limited
  3.  
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // any later version.
  8.  
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13.  
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. // mpaddock@cix.compulink.co.uk
  19.  
  20. /* Amiga headers */
  21. #define INTUI_V36_NAMES_ONLY
  22. #define INTUITION_IOBSOLETE_H
  23.  
  24. // Include correct math library
  25. #ifdef MY68881
  26. #include <m68881.h>
  27. extern int rand(void);
  28. #else
  29. #ifdef MY68881_6
  30. #include <math.h>
  31. #include <m68881.h>
  32. #define floor(d) __builtin_fpc(0x0003,d)
  33. #else
  34. #include <math.h>
  35. #endif
  36. #endif
  37.  
  38. // prevent inclusion of another math library
  39. #define LIBRARIES_MATHFFP_H
  40.  
  41. // other headers, define some non 2.02 header stuff
  42. #include <exec/types.h>
  43. #include <exec/memory.h>
  44. #include <intuition/intuition.h>
  45. #include <intuition/intuitionbase.h>
  46. #include <intuition/gadgetclass.h>
  47. #ifndef PGA_NewLook
  48. #define PGA_NewLook (PGA_Dummy + 0x000A)
  49. #endif
  50. #include <intuition/imageclass.h>
  51. #include <intuition/icclass.h>
  52. #include <devices/input.h>
  53. #include <workbench/workbench.h>
  54. #include <workbench/startup.h>
  55. #include <libraries/gadtools.h>
  56. #ifndef GTMN_FullMenu
  57. #define GTMN_FullMenu GT_TagBase+62
  58. #endif
  59. #include <libraries/asl.h>
  60.  
  61. #include <clib/exec_protos.h>
  62. #include <clib/dos_protos.h>
  63. #include <clib/layers_protos.h>
  64. #include <clib/graphics_protos.h>
  65. #include <clib/intuition_protos.h>
  66. #include <clib/input_protos.h>
  67. #include <clib/gadtools_protos.h>
  68. #include <clib/asl_protos.h>
  69. #include <clib/utility_protos.h>
  70. #include <clib/alib_protos.h>
  71.  
  72. #include <pragmas/exec_pragmas.h>
  73. #include <pragmas/dos_pragmas.h>
  74. #include <pragmas/layers_pragmas.h>
  75. #include <pragmas/graphics_pragmas.h>
  76. #include <pragmas/intuition_pragmas.h>
  77. #include <pragmas/input_pragmas.h>
  78. #include <pragmas/gadtools_pragmas.h>
  79. #include <pragmas/asl_pragmas.h>
  80. #include <pragmas/utility_pragmas.h>
  81.  
  82. #include <proto/diskfont.h>
  83. #include <proto/icon.h>
  84.  
  85. #include <devices/timer.h>
  86.  
  87. #include <clib/timer_protos.h>
  88. #include <pragmas/timer_pragmas.h>
  89.  
  90. #include <clib/alib_protos.h>
  91.  
  92. #include <rexx/errors.h>
  93. #include <pragmas/rexxsyslib_pragmas.h>
  94. #include <clib/rexxsyslib_protos.h>
  95.  
  96. #include <libraries/amigaguide.h>
  97. #include <clib/amigaguide_protos.h>
  98. #include <pragmas/amigaguide_pragmas.h>
  99.  
  100. #include <libraries/reqtools.h>
  101. #include <clib/reqtools_protos.h>
  102. #include <pragmas/reqtools.h>
  103.  
  104. #include <opal/opallib.h>
  105.  
  106. #include <libraries/dctv.h>
  107. #include <clib/dctv_protos.h>
  108. #include <pragmas/dctv_pragmas.h>
  109.  
  110. #include <libraries/nofrag.h>
  111. #include <clib/nofrag_protos.h>
  112. #ifdef LIBRARIES_NOFRAG_H
  113. #undef LIBRARIES_NOFRAG_H
  114. #endif
  115. #include <pragmas/nofrag_pragmas.h>
  116. #ifndef LIBRARIES_NOFRAG_H
  117. #define LIBRARIES_NOFRAG_H 1
  118. #endif
  119.  
  120. #include <stddef.h>
  121. #include <string.h>
  122. #include <stdio.h>
  123. #include <stdlib.h>
  124.  
  125. /* Below is not in the 2.02 version of clib/utility_protos.h
  126.                                        pragmas/utility_pragmas.h */
  127. #if INCLUDE_VERSION < 37
  128. LONG Stricmp(UBYTE *string1,UBYTE *string2);
  129. #pragma libcall UtilityBase Stricmp A2 9802
  130. #endif
  131.  
  132. // IFF header
  133. #include "iffp/ILBMapp.h"
  134.  
  135. // Progress requester
  136. #include "progress.h"
  137.  
  138. // JPEG load stuff
  139. #include "JPEG_LS/jinclude.h"
  140.  
  141. /* Wait pointer */
  142. static USHORT __chip BusyPointerData[] =
  143. {
  144.    0x0000,0x0000,
  145.    0x0400,0x07C0,0x0000,0x07C0,0x0100,0x0380,0x0000,0x07E0,
  146.    0x07C0,0x1FF8,0x1FF0,0x3FEC,0x3FF8,0x7FDE,0x3FF8,0x7FBE,
  147.    0x7FFC,0xFF7F,0x7EFC,0xFFFF,0x7FFC,0xFFFF,0x3FF8,0x7FFE,
  148.    0x3FF8,0x7FFE,0x1FF0,0x3FFC,0x07C0,0x1FF8,0x0000,0x07E0,
  149.    0x0000,0x0000,
  150. };
  151.  
  152. // Libraries
  153. extern struct ExecBase *SysBase;
  154. extern struct DosLibrary *DOSBase;
  155. extern struct IntuitionBase *IntuitionBase;
  156. extern struct Library  *GfxBase, *LayersBase, *IFFParseBase;
  157. extern struct Library *GadToolsBase, *AslBase, *UtilityBase;
  158. extern struct Library *RexxSysBase;
  159. extern struct Library *AmigaGuideBase;
  160. extern struct Library *TimerBase;
  161. extern struct Library *ReqToolsBase;
  162. extern struct Library *DCTVBase;
  163. extern struct NoFragBase *NoFragBase;
  164.  
  165. extern struct OpalBase *OpalBase;
  166.  
  167. // Help stuff
  168. extern AMIGAGUIDECONTEXT handle;
  169. extern struct NewAmigaGuide nag;
  170. extern ULONG ASig;
  171.  
  172. // nofrag.library stuff
  173. extern struct MemoryChain *Chain;
  174. #define MAXMEM 1000
  175.  
  176. #define H_Help         10
  177. #define H_Library        11
  178. #define H_ESave        12
  179. #define H_AllocVec    13
  180. #define H_OpenPoints    14
  181. #define H_Progress    15
  182. #define H_AllocPlanes 16
  183. #define H_24            17
  184. #define H_Load            18
  185. #define H_AllocIFF    19
  186. #define H_AllocILBM    20
  187. #define H_FileFormat    21
  188. #define H_SizeMatch    22
  189. #define H_Range        23
  190. #define H_MemPointsR    24
  191. #define H_CloseFile    25
  192. #define H_3Points        26
  193. #define H_Open            27
  194. #define H_ARexx        28
  195. #define H_Really        29
  196. #define HE_OldFormat    30
  197. #define HE_OpalVision 31
  198. #define HE_NoOpal        32
  199.  
  200. // 24 bitplane bitmap
  201. struct MyBitMap {
  202.     struct BitMap BitMap;
  203.     PLANEPTR xplanes[16];
  204. };
  205.  
  206. extern char                 FileName[256];    // File name buffer
  207. extern long                    OVQuality;    // OpalVision JPG quality
  208. extern BOOL                    OVFast;        // OpalVision fast format IFF
  209. extern BOOL                    OVThumb;        // OpalVision Thumbail
  210. extern BOOL                    HAM6;
  211. extern BOOL                    HAM8;
  212. extern BOOL                    BW16;
  213. extern BOOL                    BW256;
  214. extern BOOL                    DCTV3;
  215. extern BOOL                    DCTV4;
  216. extern UBYTE                 *arrayr,        // Pointers to red,green and blue
  217.                                   *arrayg,
  218.                                   *arrayb;
  219. extern BOOL                    PPM;            // PPM save ?
  220. extern UBYTE                *p[3];// chunky pointers - order for OpalVision
  221. #define RED p[0]
  222. #define BLUE p[2]
  223. #define GREEN p[1]
  224. extern UWORD        swidth;        // scaled width (in full words)
  225. extern struct RastPort     RP,            // Work Rast Ports
  226.                          TRP;
  227. extern struct MyBitMap     MyBitMap;    // Real bit map
  228. extern PLANEPTR             Planes[24];    // Bit planes
  229. extern BOOL                    CreateIcons;// Create Icons on pictures?
  230.  
  231. extern struct OpalScreen *OScrn;
  232. extern char                 *OVFormat;    // Format of OpalVision save JPG or IFF (or anything) default
  233.  
  234. extern USHORT    width, height, pwidth, pheight, pmode;
  235.  
  236. extern UBYTE *plane0;                    // Planes for temporary bit maps
  237. extern UBYTE *plane1;
  238. extern UBYTE *plane2;
  239. extern UBYTE *plane3;
  240. extern UBYTE *plane4;
  241. extern UBYTE *plane5;
  242. extern UBYTE *plane6;
  243. extern UBYTE *plane7;
  244.  
  245. extern char AnimName[];    // Buffer for file name to save
  246.  
  247. // Table of parameters
  248. extern struct {
  249.     LONG xf;                // Current frame
  250.     LONG xFrames;        // Number of frames
  251.     LONG xSingle;        // Warp or Morph
  252.     LONG xmove;            // Movement 1 to 2
  253.     LONG xr;                // red of image 1
  254.     LONG xg;                // green
  255.     LONG xb;                // blue
  256.     LONG xr2;            // red of image 2
  257.     LONG xg2;            // green
  258.     LONG xb2;            // blue
  259.     LONG xDo;            // Produce this image
  260.     LONG xrplus;        // Add red
  261.     LONG xgplus;        // green
  262.     LONG xbplus;        // blue
  263.     LONG xrminus;        // subtract red
  264.     LONG xgminus;        // subtract green
  265.     LONG xbminus;        // subtract blue
  266.     LONG xDX;            // X skip
  267.     LONG xDY;            // Y skip
  268.     LONG xStart;        // Start Frame number
  269.     LONG FILLER[32];    // Filler for future expansion
  270. } Arexx;
  271.  
  272. #define f Arexx.xf
  273. #define Frames Arexx.xFrames
  274. #define Single Arexx.xSingle
  275. #define move Arexx.xmove
  276. #define r Arexx.xr
  277. #define g Arexx.xg
  278. #define b Arexx.xb
  279. #define r2 Arexx.xr2
  280. #define g2 Arexx.xg2
  281. #define b2 Arexx.xb2
  282. #define Do Arexx.xDo
  283. #define rplus Arexx.xrplus
  284. #define gplus Arexx.xgplus
  285. #define bplus Arexx.xbplus
  286. #define rminus Arexx.xrminus
  287. #define gminus Arexx.xgminus
  288. #define bminus Arexx.xbminus
  289. #define DX Arexx.xDX
  290. #define DY Arexx.xDY
  291. #define Start Arexx.xStart
  292.  
  293. extern char buffer[256];
  294. extern char buffer1[512];
  295. extern char    *Postscript;// ARexx postscript
  296.  
  297. extern WORD x,y;                // Current coords
  298.  
  299. void help(ULONG hnum);
  300. void DisableWindow(void);
  301. void EnableWindow(void);
  302. void AddMessage(UBYTE *message);
  303.  
  304. // SaveHAMetc.c
  305. BOOL SaveBW16(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  306.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  307.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
  308. BOOL SaveBW256(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  309.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  310.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
  311. BOOL SaveHAM6(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  312.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  313.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
  314. BOOL SaveHAM8(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  315.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  316.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
  317. BOOL SaveDCTV(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  318.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  319.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp);
  320.  
  321. /* Frame clicked - irrelevant    */
  322. int
  323. FrameClicked(void) {
  324.     return 1;
  325. }
  326.  
  327.  
  328. /* Line clicked - irrelevant    */
  329. int
  330. LineClicked(void) {
  331.     return 1;
  332. }
  333.  
  334. /* Routine for when Stop clicked    */
  335. int
  336. StopClicked(void) {
  337.    struct EasyStruct EasyStruct = {
  338.       sizeof(struct EasyStruct),
  339.       0,
  340.       NULL,
  341.       NULL,
  342.       NULL,
  343.    };
  344.     UBYTE *title = "TSMorph-render";
  345.     UBYTE *body = "Really quit?";
  346.    struct Window *req;
  347.    UBYTE *gad;
  348.    ULONG ret = 2;
  349.     struct AmigaGuideMsg *agm;
  350.     ULONG signals;
  351.     struct rtHandlerInfo *rth;
  352.    // Disable the window, display a requester and reenable the window
  353.    DisableWindow();
  354.    if (ReqToolsBase) {
  355.        if (handle) {
  356.             gad = "_Quit|_Help|_Continue";
  357.        }
  358.        else {
  359.             gad = "_Quit|_Continue";
  360.        }
  361.         while (ret == 2) {
  362.             ret = CALL_HANDLER;
  363.            if (rtEZRequestTags(body,gad,NULL,NULL,
  364.                                        RT_ReqHandler, &rth,
  365.                                        RT_Window, ProgressWnd,
  366.                                        RT_Underscore, '_',
  367.                                        RTEZ_ReqTitle, title,
  368.                                        TAG_END) == CALL_HANDLER) {
  369.                 while (ret == CALL_HANDLER) {
  370.                    if (!rth->DoNotWait) {
  371.                        signals = Wait(rth->WaitMask | ASig);
  372.                    }
  373.                     ret = rtReqHandlerA(rth,signals,NULL);
  374.                    if (ret == 2) {
  375.                        help(H_Really);
  376.                    }
  377.                    if (signals & ASig) {
  378.                           while (agm = GetAmigaGuideMsg(handle)) {
  379.                              ReplyAmigaGuideMsg(agm);
  380.                          }
  381.                      }
  382.                 }
  383.            }
  384.            else {
  385.                ret = 0;
  386.            }
  387.        }
  388.     }
  389.     else {
  390.         EasyStruct.es_TextFormat = body;
  391.         EasyStruct.es_Title = title;
  392.        if (handle) {
  393.            EasyStruct.es_GadgetFormat = "Quit|Help|Continue";
  394.        }
  395.        else {
  396.            EasyStruct.es_GadgetFormat = "Quit|Continue";
  397.        }
  398.         req = BuildEasyRequest(ProgressWnd,&EasyStruct,NULL,NULL);
  399.        while ((ret = SysReqHandler(req,NULL,TRUE)) == 2) {
  400.            help(H_Really);
  401.               while (agm = GetAmigaGuideMsg(handle)) {
  402.                  ReplyAmigaGuideMsg(agm);
  403.              }
  404.        }
  405.        FreeSysRequest(req);
  406.    }
  407.    EnableWindow();
  408.     return !ret;
  409. }
  410.  
  411. /* Disables the Progress window
  412.  * Disables the 'Stop' gadget and displays a wait pointer
  413.  */
  414. void
  415. DisableWindow(void) {
  416.     if (ProgressWnd) {
  417.         GT_SetGadgetAttrs(ProgressGadgets[GDX_Stop],ProgressWnd,NULL,GA_Disabled,TRUE,TAG_END);
  418.         SetPointer(ProgressWnd, BusyPointerData, 16, 16, -6, 0);
  419.     }
  420. }
  421.  
  422. /* Enables the Progress window
  423.  * Enables the 'Stop' gadget and clears the pointer
  424.  */
  425. void
  426. EnableWindow(void) {
  427.     if (ProgressWnd) {
  428.         GT_SetGadgetAttrs(ProgressGadgets[GDX_Stop],ProgressWnd,NULL,GA_Disabled,FALSE,TAG_END);
  429.         ClearPointer(ProgressWnd);
  430.     }
  431. }
  432.  
  433. APTR
  434. MyAllocVec(ULONG size,ULONG requirements) {
  435.     ULONG *MyMem;
  436.     if (Chain && (size < MAXMEM)) {
  437.         if (MyMem = AllocVecItem(Chain,size+4,requirements)) {
  438.             *MyMem = size;
  439.             return ++MyMem;
  440.         }
  441.         else {
  442.             return NULL;
  443.         }
  444.     }
  445.     else {
  446.         if (MyMem = AllocVec(size+4,requirements)) {
  447.             *MyMem = size;
  448.             return ++MyMem;
  449.         }
  450.         else {
  451.             return NULL;
  452.         }
  453.     }
  454. }
  455.  
  456. void MyFreeVec(APTR memptr) {
  457.     ULONG *MyMem;
  458.     MyMem = memptr;
  459.     --MyMem;
  460.     if (Chain && (*MyMem < MAXMEM)) {
  461.         FreeVecItem(Chain,MyMem);
  462.     }
  463.     else {
  464.         FreeVec(MyMem);
  465.     }
  466. }
  467.  
  468. APTR
  469. MyAllocMem(ULONG size,ULONG requirements) {
  470.     ULONG *MyMem;
  471.     if (Chain && (size < MAXMEM)) {
  472.         if (MyMem = AllocItem(Chain,size+4,requirements)) {
  473.             *MyMem = size;
  474.             return ++MyMem;
  475.         }
  476.         else {
  477.             return NULL;
  478.         }
  479.     }
  480.     else {
  481.         if (MyMem = AllocMem(size+4,requirements)) {
  482.             *MyMem = size;
  483.             return ++MyMem;
  484.         }
  485.         else {
  486.             return NULL;
  487.         }
  488.     }
  489. }
  490.  
  491. void MyFreeMem(APTR memptr,ULONG size) {
  492.     ULONG *MyMem;
  493.     MyMem = memptr;
  494.     --MyMem;
  495.     if (Chain && (*MyMem < MAXMEM)) {
  496.         FreeItem(Chain,MyMem,size+4);
  497.     }
  498.     else {
  499.         FreeMem(MyMem,size+4);
  500.     }
  501. }
  502.  
  503.  
  504. // Note no free() is needed
  505. APTR
  506. Mymalloc(ULONG size) {
  507.     if (Chain && (size < MAXMEM)) {
  508.         return AllocItem(Chain,size,0);
  509.     }
  510.     else {
  511.         return malloc(size);
  512.     }
  513. }
  514.  
  515. APTR
  516. Mystrdup(UBYTE *str) {
  517.     UBYTE *t;
  518.     if (t = Mymalloc(strlen(str)+1)) {
  519.         strcpy(t,str);
  520.     }
  521.     else {
  522.         return NULL;
  523.     }
  524. }
  525.  
  526. /* Display an error message
  527.  * ErrorMessage    : The main text
  528.  * Gadget            : Text for one gadget
  529.  * extra                : more of the text
  530.  * helpnum            : Number of a help node
  531.  *
  532.  * See the TSMorph source code for more of how this actually works
  533.  */
  534. void
  535. Error(char *ErrorMessage,char *Gadget,char *extra,ULONG helpnum) {
  536.    struct EasyStruct EasyStruct = {
  537.       sizeof(struct EasyStruct),
  538.       0,
  539.       NULL,
  540.       NULL,
  541.       NULL
  542.    };
  543.    UBYTE *title = "TSMorph-render Error";
  544.    struct Window *req;
  545.    UBYTE gad[32] = "Help|";
  546.    UBYTE gad1[32] = "_Help|_";
  547.    ULONG ret = CALL_HANDLER;
  548.     struct AmigaGuideMsg *agm;
  549.     ULONG signals;
  550.     struct rtHandlerInfo *rth;
  551.     // Disable the window and display the requester
  552.    DisableWindow();
  553.    if (ReqToolsBase) {
  554.        if (!handle) {
  555.             strcpy(gad1,"_");
  556.        }
  557.         strcat(gad1,Gadget);
  558.         while (ret) {
  559.             ret = CALL_HANDLER;
  560.            if (rtEZRequestTags(ErrorMessage,gad1,NULL,&extra,
  561.                                        RT_ReqHandler, &rth,
  562.                                        RT_Window, ProgressWnd,
  563.                                        RT_Underscore, '_',
  564.                                        RTEZ_ReqTitle, title,
  565.                                        TAG_END) == CALL_HANDLER) {
  566.                 while (ret == CALL_HANDLER) {
  567.                    if (!rth->DoNotWait) {
  568.                        signals = Wait(rth->WaitMask | ASig);
  569.                    }
  570.                     ret = rtReqHandlerA(rth,signals,NULL);
  571.                    if (ret == 1) {
  572.                        help(helpnum);
  573.                    }
  574.                    if (signals & ASig) {
  575.                           while (agm = GetAmigaGuideMsg(handle)) {
  576.                              ReplyAmigaGuideMsg(agm);
  577.                          }
  578.                      }
  579.                 }
  580.            }
  581.            else {
  582.                ret = 0;
  583.            }
  584.        }
  585.    }
  586.    else {
  587.         EasyStruct.es_TextFormat = ErrorMessage;
  588.         EasyStruct.es_Title = title;
  589.        if (handle) {
  590.            strcat(gad,Gadget);
  591.        }
  592.        else {
  593.            strcpy(gad,Gadget);
  594.        }
  595.         EasyStruct.es_GadgetFormat = gad;
  596.         req = BuildEasyRequest(ProgressWnd,&EasyStruct,NULL,extra);
  597.         while (ret) {
  598.             signals  = Wait((1L << req->UserPort->mp_SigBit) | ASig);
  599.             if (signals & (1L << req->UserPort->mp_SigBit)) {
  600.                ret = SysReqHandler(req,NULL,FALSE);
  601.                if (ret == 1) {
  602.                    help(helpnum);
  603.                }
  604.            }
  605.            if (signals & ASig) {
  606.                   while (agm = GetAmigaGuideMsg(handle)) {
  607.                      ReplyAmigaGuideMsg(agm);
  608.                  }
  609.             }
  610.        }
  611.        FreeSysRequest(req);
  612.    }
  613.    EnableWindow();
  614. }
  615.  
  616. /* Tries to execute a Rexx script
  617.  * msgtxt = name of script
  618.  * IgnoreError = TRUE then do not display error message
  619.  * Returns:    error message
  620.  */
  621. LONG
  622. SendRxMsg(char *msgtxt,BOOL IgnoreError) {
  623.     struct MsgPort *reply_port;
  624.     struct MsgPort *rx_port;
  625.     struct RexxMsg *rx_msg;
  626.     LONG                 ret             = RC_FATAL;
  627.  
  628.     if (reply_port = CreateMsgPort()) {
  629.        if (rx_msg = CreateRexxMsg(reply_port,"TSM","REXX")) {
  630.           rx_msg->rm_Args[0] = msgtxt;
  631.             if (FillRexxMsg(rx_msg,1,0)) {
  632.                 rx_msg->rm_Action = RXCOMM;
  633.                 Forbid();
  634.                 if (rx_port = (struct MsgPort *)FindPort("REXX")) {
  635.                   PutMsg(rx_port, (struct Message *)rx_msg);
  636.                   Permit();
  637.                   WaitPort(reply_port);
  638.                   ReplyMsg(GetMsg(reply_port));
  639.                   ret = rx_msg->rm_Result1;
  640.                  }
  641.                 else {
  642.                   Permit();
  643.                 }
  644.                 ClearRexxMsg(rx_msg, 1);
  645.           }
  646.              DeleteRexxMsg(rx_msg);
  647.         }
  648.         DeleteMsgPort(reply_port);
  649.       }
  650.     // Display an error message (if required)
  651.       if (!IgnoreError && ret) {
  652.           Error("Error sending ARexx message\n'%s'","Quit",msgtxt,H_ARexx);
  653.       }
  654.       return ret;
  655. }
  656.  
  657. /* Handle 'Help' key    */
  658. int
  659. ProgressRawKey(void) {
  660.     switch (ProgressMsg.Code) {
  661.     case 0x5f:
  662.         help(H_Help);
  663.     }
  664.     return 1;
  665. }
  666.  
  667. // save an image
  668. BOOL
  669. SaveFile(void) {
  670.     struct ILBMInfo     *ilbm;        // IFF stuff to save
  671.     BPTR                    fh;            // File handle for PPM
  672.     BOOL OkFlag = TRUE;
  673.     struct BitMap     TBM;                // Temp bit map
  674.     struct DiskObject *MyDiskObject;    // The Icon
  675.     char                    *iconname;    // iconname
  676.     char                    *iconname1;    // alternate iconname
  677.     if (!PPM) {
  678.         // Not PPM
  679.         if (OVFormat) {
  680.             // OpalVision so convert RGB to OpalVision
  681.             RGBtoOV(OScrn,p,0,0,swidth,height);
  682.         }
  683.         else {
  684.             // Set up BitMap
  685.             InitBitMap(&MyBitMap,(DCTV3?3:((DCTV4|BW16)?4:(HAM6?6:((HAM8|BW256)?8:24)))),width,height);
  686.             InitRastPort(&RP);
  687.             RP.BitMap = &MyBitMap;
  688.             InitRastPort(&TRP);
  689.             InitBitMap(&TBM,(DCTV3?3:((DCTV4|BW16)?4:(HAM6?6:((HAM8|BW256)?8:8)))),width,1);
  690.             TBM.BytesPerRow = (((width+15)>>4)<<1);
  691.             TBM.Rows = 1;
  692.             TRP.BitMap = &TBM;
  693.             TBM.Planes[0]=plane0;
  694.             TBM.Planes[1]=plane1;
  695.             TBM.Planes[2]=plane2;
  696.             TBM.Planes[3]=plane3;
  697.             TBM.Planes[4]=plane4;
  698.             TBM.Planes[5]=plane5;
  699.             TBM.Planes[6]=plane6;
  700.             TBM.Planes[7]=plane7;
  701.             if (!HAM6 && !HAM8 && !BW16 && !BW256 && !DCTV3 && !DCTV4) {
  702.                 // i.e. 24 bit ILBM?
  703.                 // so convert chunky to planar
  704.                 MyBitMap.BitMap.Depth = 8;
  705.                 MyBitMap.BitMap.Planes[0] = Planes[0];
  706.                 MyBitMap.BitMap.Planes[1] = Planes[1];
  707.                 MyBitMap.BitMap.Planes[2] = Planes[2];
  708.                 MyBitMap.BitMap.Planes[3] = Planes[3];
  709.                 MyBitMap.BitMap.Planes[4] = Planes[4];
  710.                 MyBitMap.BitMap.Planes[5] = Planes[5];
  711.                 MyBitMap.BitMap.Planes[6] = Planes[6];
  712.                 MyBitMap.BitMap.Planes[7] = Planes[7];
  713.                 WritePixelArray8(&RP,0,0,width-1,height-1,RED,&TRP);
  714.                 WaitBlit();
  715.                 MyBitMap.BitMap.Planes[0] = Planes[8];
  716.                 MyBitMap.BitMap.Planes[1] = Planes[9];
  717.                 MyBitMap.BitMap.Planes[2] = Planes[10];
  718.                 MyBitMap.BitMap.Planes[3] = Planes[11];
  719.                 MyBitMap.BitMap.Planes[4] = Planes[12];
  720.                 MyBitMap.BitMap.Planes[5] = Planes[13];
  721.                 MyBitMap.BitMap.Planes[6] = Planes[14];
  722.                 MyBitMap.BitMap.Planes[7] = Planes[15];
  723.                 WritePixelArray8(&RP,0,0,width-1,height-1,GREEN,&TRP);
  724.                 WaitBlit();
  725.                 MyBitMap.BitMap.Planes[0] = Planes[16];
  726.                 MyBitMap.BitMap.Planes[1] = Planes[17];
  727.                 MyBitMap.BitMap.Planes[2] = Planes[18];
  728.                 MyBitMap.BitMap.Planes[3] = Planes[19];
  729.                 MyBitMap.BitMap.Planes[4] = Planes[20];
  730.                 MyBitMap.BitMap.Planes[5] = Planes[21];
  731.                 MyBitMap.BitMap.Planes[6] = Planes[22];
  732.                 MyBitMap.BitMap.Planes[7] = Planes[23];
  733.                 WritePixelArray8(&RP,0,0,width-1,height-1,BLUE,&TRP);
  734.                 WaitBlit();
  735.             }
  736.             // Reset up BitMap
  737.             MyBitMap.BitMap.Depth = (DCTV3?3:((DCTV4|BW16)?4:(HAM6?6:((HAM8|BW256)?8:24))));
  738.             MyBitMap.BitMap.Planes[0] = Planes[0];
  739.             MyBitMap.BitMap.Planes[1] = Planes[1];
  740.             MyBitMap.BitMap.Planes[2] = Planes[2];
  741.             MyBitMap.BitMap.Planes[3] = Planes[3];
  742.             MyBitMap.BitMap.Planes[4] = Planes[4];
  743.             MyBitMap.BitMap.Planes[5] = Planes[5];
  744.             MyBitMap.BitMap.Planes[6] = Planes[6];
  745.             MyBitMap.BitMap.Planes[7] = Planes[7];
  746.             MyBitMap.BitMap.Planes[8] = Planes[8];
  747.             MyBitMap.BitMap.Planes[9] = Planes[9];
  748.             MyBitMap.BitMap.Planes[10] = Planes[10];
  749.             MyBitMap.BitMap.Planes[11] = Planes[11];
  750.             MyBitMap.BitMap.Planes[12] = Planes[12];
  751.             MyBitMap.BitMap.Planes[13] = Planes[13];
  752.             MyBitMap.BitMap.Planes[14] = Planes[14];
  753.             MyBitMap.BitMap.Planes[15] = Planes[15];
  754.             MyBitMap.BitMap.Planes[16] = Planes[16];
  755.             MyBitMap.BitMap.Planes[17] = Planes[17];
  756.             MyBitMap.BitMap.Planes[18] = Planes[18];
  757.             MyBitMap.BitMap.Planes[19] = Planes[19];
  758.             MyBitMap.BitMap.Planes[20] = Planes[20];
  759.             MyBitMap.BitMap.Planes[21] = Planes[21];
  760.             MyBitMap.BitMap.Planes[22] = Planes[22];
  761.             MyBitMap.BitMap.Planes[23] = Planes[23];
  762.         }
  763.     }
  764.     // Set up output file name
  765.    sprintf(FileName,AnimName,f+Start-1);
  766.     if (PPM) {
  767.         // PPM Save is very simple P6 mode
  768.         AddMessage("Saving PPM image");
  769.         if (fh = Open(FileName,MODE_NEWFILE)) {
  770.             sprintf(buffer,"P6\n%ld %ld\n255\n",width,height);
  771.             FPuts(fh,buffer);
  772.             arrayr=RED;
  773.             arrayg=GREEN;
  774.             arrayb=BLUE;
  775.             // loop thru lines
  776.             for (y=0;
  777.                   (y<height) && OkFlag;
  778.                   y++) {
  779.                 // Loop thru columns
  780.                 for (x=0;
  781.                       x < width;
  782.                       x++) {
  783.                     FPutC(fh,*arrayr);
  784.                     FPutC(fh,*arrayg);
  785.                     FPutC(fh,*arrayb);
  786.                     arrayr++;
  787.                     arrayg++;
  788.                     arrayb++;
  789.                 }
  790.                 // skip part word at end of line
  791.                 arrayr += (swidth - width);
  792.                 arrayg += (swidth - width);
  793.                 arrayb += (swidth - width);
  794.             }
  795.             if (!Close(fh)) {
  796.                 OkFlag = FALSE;
  797.             }
  798.         }
  799.         else {
  800.             OkFlag = FALSE;
  801.         }
  802.     }
  803.     else {
  804.         // Save non PPM
  805.         if (OVFormat) {
  806.             // Save OpalVision
  807.             if (!strcmp(OVFormat,"JPG")) {
  808.                 AddMessage("Saving Opal JPEG image");
  809.                 // Save JPEG
  810.                 OkFlag = !SaveJPEG24(OScrn,FileName,(OVThumb?0:NOTHUMBNAIL),OVQuality);
  811.             }
  812.             else {
  813.                 AddMessage("Saving Opal IFF24 image");
  814.                 // Save IFF
  815.                 OkFlag = !SaveIFF24(OScrn,FileName,NULL,(OVThumb?0:NOTHUMBNAIL)|(OVFast?OVFASTFORMAT:0));
  816.             }
  817.         }
  818.         else {
  819.             if (HAM6) {
  820.                 AddMessage("Saving HAM6 image");
  821.                 OkFlag = SaveHAM6(FileName,width,height,swidth,
  822.                                         pwidth,pheight,pmode,
  823.                                         RED,GREEN,BLUE,&RP,&TRP);
  824.             }
  825.             else {
  826.                 if (HAM8) {
  827.                     AddMessage("Saving HAM8 image");
  828.                     OkFlag = SaveHAM8(FileName,width,height,swidth,
  829.                                             pwidth,pheight,pmode,
  830.                                             RED,GREEN,BLUE,&RP,&TRP);
  831.                 }
  832.                 else {
  833.                     if (BW16) {
  834.                         AddMessage("Saving BW16 image");
  835.                         OkFlag = SaveBW16(FileName,width,height,swidth,
  836.                                                 pwidth,pheight,pmode,
  837.                                                 RED,GREEN,BLUE,&RP,&TRP);
  838.                     }
  839.                     else {
  840.                         if (BW256) {
  841.                             AddMessage("Saving BW256 image");
  842.                             OkFlag = SaveBW256(FileName,width,height,swidth,
  843.                                                      pwidth,pheight,pmode,
  844.                                                      RED,GREEN,BLUE,&RP,&TRP);
  845.                         }
  846.                         else {
  847.                             if (DCTV3 || DCTV4) {
  848.                                 AddMessage(DCTV3?"Saving DCTV3 image":"Saving DCTV4 image");
  849.                                 OkFlag = SaveDCTV(FileName,width,height,swidth,
  850.                                                         pwidth,pheight,pmode,
  851.                                                         RED,GREEN,BLUE,&RP,&TRP);
  852.                             }
  853.                             else {
  854.                                 AddMessage("Saving ILBM24 image");
  855.                                 // allocate some IFF stuff
  856.                                 if (ilbm = (struct ILBMInfo *)MyAllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  857.                                     if (ilbm->ParseInfo.iff = AllocIFF()) {
  858.                                         OkFlag = !saveilbm(ilbm, &MyBitMap, pmode,
  859.                                                                  width,  height, pwidth, pheight,
  860.                                                                  NULL, 0, 0,    /* colortable */
  861.                                                                  mskNone, 0,    /* masking, transparent */
  862.                                                                  NULL, NULL,     /* chunklists */
  863.                                                                  FileName);
  864.                                         // Close everything down cleanly
  865.                                         FreeIFF(ilbm->ParseInfo.iff);
  866.                                     }
  867.                                     else {
  868.                                         OkFlag = FALSE;
  869.                                     }
  870.                                     MyFreeMem(ilbm,sizeof(struct ILBMInfo));
  871.                                 }
  872.                                 else {
  873.                                     OkFlag = FALSE;
  874.                                 }
  875.                             }
  876.                         }
  877.                     }
  878.                 }
  879.             }
  880.         }
  881.     }
  882.     if (OkFlag) {
  883.         if (CreateIcons) {
  884.             // try to save an Icon
  885.             if (MyDiskObject = GetDiskObject(FileName)) {
  886.                 // Do not overwrite if already present
  887.                 FreeDiskObject(MyDiskObject);
  888.             }
  889.             else {
  890.                 // Set up two possible names
  891.                 if (OVFormat) {
  892.                     if (!strcmp(OVFormat,"JPG")) {
  893.                         iconname = "ENV:TSMorph/def_jpg";
  894.                         iconname1 = "ENV:SYS/def_jpg";
  895.                     }
  896.                     else {
  897.                         iconname = "ENV:TSMorph/def_iff";
  898.                         iconname1 = "ENV:SYS/def_iff";
  899.                     }
  900.                 }
  901.                 else {
  902.                     if (PPM) {
  903.                         iconname = "ENV:TSMorph/def_ppm";
  904.                         iconname1 = "ENV:SYS/def_ppm";
  905.                     }
  906.                     else {
  907.                         if (BW16) {
  908.                             iconname = "ENV:TSMorph/def_bw16";
  909.                             iconname1 = "ENV:SYS/def_bw16";
  910.                         }
  911.                         else {
  912.                             if (BW256) {
  913.                                 iconname = "ENV:TSMorph/def_bw256";
  914.                                 iconname1 = "ENV:SYS/def_bw256";
  915.                             }
  916.                             else {
  917.                                 if (HAM6) {
  918.                                     iconname = "ENV:TSMorph/def_ham6";
  919.                                     iconname1 = "ENV:SYS/def_ham6";
  920.                                 }
  921.                                 else {
  922.                                     if (HAM8) {
  923.                                         iconname = "ENV:TSMorph/def_ham8";
  924.                                         iconname1 = "ENV:SYS/def_ham8";
  925.                                     }
  926.                                     else {
  927.                                         if (DCTV3) {
  928.                                             iconname = "ENV:TSMorph/def_dctv3";
  929.                                             iconname1 = "ENV:SYS/def_dctv3";
  930.                                         }
  931.                                         else {
  932.                                             if (DCTV4) {
  933.                                                 iconname = "ENV:TSMorph/def_dctv4";
  934.                                                 iconname1 = "ENV:SYS/def_dctv4";
  935.                                             }
  936.                                             else {
  937.                                                 iconname = "ENV:TSMorph/def_ilbm";
  938.                                                 iconname1 = "ENV:SYS/def_ilbm";
  939.                                             }
  940.                                         }
  941.                                     }
  942.                                 }
  943.                             }
  944.                         }
  945.                     }
  946.                 }
  947.                 // Try two names, as last resort use default project
  948.                 if ((MyDiskObject = GetDiskObject(iconname)) ||
  949.                      (MyDiskObject = GetDiskObject(iconname1)) ||
  950.                      (MyDiskObject = GetDefDiskObject(WBPROJECT))) {
  951.                     PutDiskObject(FileName,MyDiskObject);
  952.                     FreeDiskObject(MyDiskObject);
  953.                 }
  954.             }
  955.         }
  956.     }
  957.     if (!OkFlag) {
  958.         Error("Error saving file '%s'","Quit",FileName,H_ESave);
  959.     }
  960.     else {
  961.         // Post image processing
  962.         if (strcmp(Postscript,"OFF")) {
  963.             strcpy(buffer,Postscript);
  964.             strcat(buffer," %ld %ld %ld %s");
  965.             sprintf(buffer1,buffer,f+Start-1,Frames,Single,FileName);
  966.             AddMessage("Postscript processing");
  967.             OkFlag = !SendRxMsg(buffer1,FALSE);
  968.         }
  969.     }
  970.     return OkFlag;
  971. }
  972.